﻿from doctest import master
import tkinter as tk, tkinter.ttk as ttk, tkinter.simpledialog, tkinter.messagebox
import ui_data, channel, protocol, raw 




class Dialog_Conf(tkinter.simpledialog.Dialog):
    """用于重载 tkinter.simpledialog.Dialog
    窗口分成三个部分，用三个部分，第一部分选择类型，第二部分是通道设置，第三部分是规约设置
    """
    def __init__(self, parent, dqrecv ) -> None:
        channel.CData.AddType(channel.TCPS)
        channel.CData.AddType(channel.TCPC)
        channel.CData.AddType(channel.UDP)
        channel.CData.AddType(channel.COM)
        self.dqrecv = dqrecv
        self.CHANNEL:dict = channel.CData.GetTypes()
        protocol.PData.AddType(raw.RAW)
        self.PROTOCOL:dict = protocol.PData.GetTypes()
        # {"RAW":self.window_raw_conf, 
        #                 "ModbusSlave":self.window_modbusslave_conf,  # modbus 从设备（子设备/数据源）
        #                 "ModbusMaster":self.window_modbusmaster_conf, # modbus 主设备（主设备/采集数据）
        #                 }
        self.pChannelSel:ttk.Combobox = None
        # self.pChannelWindow:tk.LabelFrame = None
        self.pProtocolSel:ttk.Combobox = None
        # self.pProtocolWindow:tk.LabelFrame = None
        self.data:ui_data.AData = ui_data.AData() # 保存参数
        self.applied = False
        super().__init__(parent, "参数设置")
        pass
    
    # def buttonbox(self) -> None:
    #     """不显示默认按钮"""
    #     # return super().buttonbox()
    #     pass
    
    def body(self, master) -> None: 
        """参数设置的窗口 """
        # if master is not None:
        # self.geometry("%dx%d+%d+%d" % (600,500, master.winfo_rootx(), master.winfo_rooty()))

        self.pFrame:tk.PanedWindow = tk.PanedWindow(master,  orient="vertical" , showhandle=True,width=550, height=450)
        self.pFrame.pack(fill="both", expand = 1)
        self.pChoose = tk.LabelFrame(self.pFrame,name="choose", text="请选择", labelanchor="nw")
        self.pFrame.add(self.pChoose)
        # self.pChannelWindow = tk.LabelFrame(pFrame, text="通道设置", labelanchor="nw")
        # pFrame.add(self.pChannelWindow)
        # self.pProtocolWindow = tk.LabelFrame(pFrame, text="规约设置", labelanchor="nw",height=100)
        # pFrame.add(self.pProtocolWindow)
        
        self.pChannelSel = ttk.Combobox(self.pChoose, state="readonly", value=list(self.CHANNEL.keys()))
        self.pChannelSel.current(0)
        self.pChannelSel.grid(column=0,row=0)
        self.pChannelSel.bind("<<ComboboxSelected>>", func=self.on_channel_change)
        self.pProtocolSel:ttk.Combobox = ttk.Combobox(self.pChoose, state="readonly", value=list(self.PROTOCOL.keys()))
        self.pProtocolSel.grid(column=1,row=0)
        self.pProtocolSel.current(0)
        self.pProtocolSel.bind("<<ComboboxSelected>>", func=self.on_protocol_change)
        
        pConfOk = tk.Button(self.pChoose, text="设置", command=self.ok )
        pConfOk.grid(column=2, row=0)
        pConfCancel = tk.Button(self.pChoose, text="退出", command=self.cancel )
        pConfCancel.grid(column=10, row=0)
        pConfOk.bind("<Return>", self.ok)
        pConfCancel.bind("<Escape>", self.cancel)

        self.pChannelSel.event_generate("<<ComboboxSelected>>") #模拟选择 TCPS的事件
        self.pProtocolSel.event_generate("<<ComboboxSelected>>")  #模拟选择 RAW 的事件
        #将窗口置于父窗口中间
        # p_w,p_h,p_x,p_y = (self.master.winfo_width(), self.master.winfo_height(), self.master.winfo_x(),self.master.winfo_y())
        # s_w,s_h,s_x,s_y = (self.winfo_width(), self.winfo_height(), self.winfo_x(),self.winfo_y())
        # self.bind("<Configure>", self.resize) # 窗口 resize事件
        # self.geometry(str(s_w)+"x"+ str(s_h)+"+0+0")
        pass
    
    # def cancel(self, event=None):
    #     self.data.err = 0
    #     super().cancel(event)
    
    def apply(self):
        """处理数据"""
        self.applied = True
        self.data.channel.setattr(id = ui_data.get_UID())
        self.data.channel.apply()
        self.data.protocol.apply()
        try:
            self.data.channel.createfd()
        except Exception as e:
            # tkinter.messagebox.showerror(title="创建\""+ self.data.channel.type + "\"错误", message="通道" + self.data.channel.info + "创建出错："  + e)
            if(self.data.channel.fd):
                self.data.channel.fd.close()
            self.data.err = e
            return
        
        # return self.data
        pass
    
    def validate(self):
        """数据有效性检查"""
        return (self.data.channel.validate() and self.data.protocol.validate() )

    def set_sub_window(self, t, cw, cw_args):
        """设置子窗口, 先删除原有窗口"""
        for item in self.pFrame.panes():
            widget = self.pFrame.nametowidget(item)
            if( widget._name == t):
                self.pFrame.remove(widget)
                widget.destroy()
                break
        if(t == "channel"):
            m , h = cw.GUI(*cw_args)
            self.pFrame.add(m, after=self.pChoose)
            self.pFrame.paneconfigure(m, sticky="nwes", height= h)
            pass
        elif(t == "protocol"):
            self.pFrame.add(cw.GUI(*cw_args) )
            # print(ow["channel"].winfo_geometry(), ow["channel"].winfo_x(), ow["channel"].winfo_rooty(), ow["channel"].winfo_height())
            # self.pFrame.paneconfigure(ow["channel"], sticky="nwes", height= ow["channel"].winfo_height())
            pass
        
    def on_channel_change(self, event) -> None:
        channel = self.pChannelSel.get()
        if(channel in self.CHANNEL):
            if channel== "COM":
                self.data.channel = self.CHANNEL[channel](self.dqrecv)
            else:
                self.data.channel = self.CHANNEL[channel]()
            self.set_sub_window("channel", self.data.channel , (self.pFrame, self.data.channel,))
        pass
    
    def on_protocol_change(self, event) -> None:
        protocol = self.pProtocolSel.get()
        if(protocol in self.PROTOCOL):
            self.data.protocol = self.PROTOCOL[protocol]()
            self.set_sub_window("protocol", self.data.protocol , (self.pFrame,self.data.protocol,))
        pass


def get_conf_and_set(parent, UI):
    d = Dialog_Conf(parent, UI.dqrecv)
    if not d.applied:
        return 
    if( d.data.err != None): 
        tkinter.messagebox.showerror(title="创建\""+ d.data.channel.type + "\"错误", 
                                    message="通道" + d.data.channel.info + "创建出错：" + str(d.data.err))
        return

    ml = UI.sml.add(d.data)
    mf = UI.smf.add(d.data)
    ms = UI.sms.add(d.data)
    d.data.protocol.set(ml=ml, mf=mf, ms=ms)
    UI.ADATA[d.data.channel.id] = d.data
    UI.smf.disable(d.data) # 刚创建时 禁止 响应用户
    UI.log("成功", "创建："+ str(d.data.channel.id) + " " + d.data.channel.info + " / " + d.data.protocol.info )
    pass

if __name__ == '__main__':
    pass